﻿using Core.DataAccess.Model.Project.Queue;
using Core.Framework.Loger;
using Core.Framework.Model.WebSockets;
using Core.Framework.Redis.Queue_Helper;
using Core.Service.TaskHandle.Task_Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using Core.Framework.Util;

namespace Core.Service.TaskHandle.Task_Listener
{
    /// <summary>
    /// Template = WebSocketMidWare.Template
    /// [需保持一致]
    /// </summary>
    [Listenner(Template = "WebSocket")]
    public class WebSocket_Linstener : BaseMQMsgListener, IMQMsgListener
    {
        public DoWork_Out DoWork(MessageQueue messageQueue)
        {
            try
            {
                messageQueue.RetryCount++;

                var json = this.StructureParameter(messageQueue);

                var outModel = new DoWork_Out
                {
                    OK = true,
                    Message = messageQueue,
                    Action = messageQueue.Message.MessageType.Equals(MessageTypeEnum.Single) ? "SingleNull" : "GroupNull"
                };

                if (messageQueue.RetryCount > 5)
                    return outModel;

                Func<KeyValuePair<WebSocket, ClientInfo>, bool> where = a =>
                    a.Value.User.Subscription.Contains(messageQueue.Message.MessageKey)
                    && a.Value.Project.ProjectToken == messageQueue.ClientInfo.Project.ProjectToken;

                var results = WebSocketApplication.ClientsPool.Where(where);

                if (results.Where(a => a.Key.State == WebSocketState.Open).Count() > 0)
                    foreach (var client in results)
                        try
                        {
                            base.SendMessage(client.Key, json);
                            RunningLoger.Consum($"ClientToken:{client.Value.ClientToken};SendMessage:{messageQueue.TryToJson()}");
                            outModel.Action = "";
                        }
                        catch (Exception e)
                        {
                            RunningLoger.Warn($"ClientToken:{client.Value.ClientToken};SendMessageError:{e.Message}");
                            outModel.OK = false;
                            outModel.Parameters = new object[] { e.Message, 1000 * messageQueue.RetryCount };
                            outModel.Action = "error";
                            WebSocketApplication.ClientsPool.TryRemove(client.Key, out ClientInfo modelClientInfo);
                        }
                        
                else
                {
                    // 检查在线状态 移除
                    if (results.Count() > 0)
                    {
                        foreach (var item in results)
                        {
                            WebSocketApplication.ClientsPool.TryRemove(item.Key, out ClientInfo modelClientInfo);
                            RunningLoger.Info($"检查在线状态移除:当前状态为{item.Key.State}，{modelClientInfo.TryToJson()}");
                            item.Key.Dispose();
                        }

                        return new DoWork_Out
                        {
                            Message = messageQueue,
                            OK = false,
                            Parameters = new object[] { "暂无可用客户端", 1000 * messageQueue.RetryCount },
                            Action = "error"
                        };
                    }
                }
                    

                return outModel;
            }
            catch (Exception e)
            {
                RunningLoger.Error("WebSocket_Linstener:" + e.Message);
                return new DoWork_Out {
                    OK = false,
                    Parameters = new object[]{ e.Message, 1000 * messageQueue.RetryCount },
                    Action = "error"
                };
            }
        }

        public void Errer(DoWork_Out model)
        {
            RedisQueueHelper.SortedPush(
                RedisQueueHelperParameter.Queue, 
                JsonConvert.SerializeObject(model.Message),
                (double)model.Parameters[1]);
        }

        public void Success(DoWork_Out model)
        {

            // 1. 存储在 redis list
            // 2. 满 （10 -100） / 条 写入数据库
            // 3. 用户登录 查询 redis list 存在即移除
            // 4. 数据量较小时 每10分钟查询 redis list 存入数据库

            // case "GroupNull":
            // case "SingleNull":
            if (model.Action.Equals("SingleNull"))
                RedisQueueHelper.ListPush(RedisQueueHelperParameter.SingleNull, JsonConvert.SerializeObject(model.Message));

            RedisQueueHelper.ListPush(
                RedisQueueHelperParameter.History,
                JsonConvert.SerializeObject(model.Message));

        }

    }
}
